home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Programming / tek / kn / amiga / visual.c < prev   
Encoding:
C/C++ Source or Header  |  2001-05-25  |  21.7 KB  |  1,089 lines

  1.  
  2. /*
  3. **    TEKlib
  4. **    (C) 2001 TEK neoscientists
  5. **    all rights reserved.
  6. **
  7. **    AmigaOS 3.x visual backend
  8. */
  9.  
  10.  
  11. #include <tek/type.h>
  12. #include <tek/array.h>
  13. #include <tek/visual.h>
  14. #include <tek/kn/visual.h>
  15. #include <tek/kn/amiga/exec.h>
  16.  
  17. #include <intuition/intuition.h>
  18. #include <libraries/cybergraphics.h>
  19. #include <guigfx/guigfx.h>
  20. #include <exec/execbase.h>
  21.  
  22. #include <proto/graphics.h>
  23. #include <proto/cybergraphics.h>
  24. #include <proto/intuition.h>
  25. #include <proto/diskfont.h>
  26. #include <proto/gadtools.h>
  27. #include <proto/dos.h>
  28. #include <proto/utility.h>
  29. #include <proto/exec.h>
  30. #include <proto/guigfx.h>
  31.  
  32.  
  33. #define SysBase *((struct ExecBase **) 4L)
  34.  
  35.  
  36. /*
  37. **    structures
  38. **
  39. */
  40.  
  41. struct screen_amiga
  42. {
  43.     struct Screen *screen;
  44.     char *title;
  45.  
  46.     struct Library *intuitionbase;
  47.     struct Library *gfxbase;
  48.     struct Library *guigfxbase;
  49.     struct Library *gadtoolsbase;
  50. };
  51.  
  52.  
  53. struct window_amiga
  54. {
  55.     struct Window *window;
  56.  
  57.     UWORD winwidth, winheight;
  58.     UWORD innerwidth, innerheight;
  59.  
  60.     WORD otherwinpos[4];            /* alternate window position x,y,w,h */
  61.  
  62.     ULONG idcmpmask;
  63.  
  64.     struct screen_amiga *scr;
  65.  
  66.     int windowbusycount;            /* nest count */
  67.  
  68.     BOOL sizable;
  69. };
  70.  
  71.  
  72. struct visual_amiga
  73. {
  74.     struct screen_amiga *screen;
  75.     struct window_amiga *window;
  76.  
  77.     UWORD amigapentab[256];
  78.     ULONG bgpen, fgpen;
  79.     
  80.     APTR drawhandle;            /* guigfx drawhandle */
  81.     APTR ddh;                    /* guigfx directdrawhandle */
  82.     TINT16 ddhw, ddhh;            /* directdrawhandle dimensions */
  83. };
  84.  
  85.  
  86.  
  87. /*
  88. **    internal prototypes
  89. **
  90. */
  91.  
  92. static void amiga_deletescreen(struct screen_amiga *amigascreen);
  93. static struct screen_amiga *amiga_createscreen(char *title);
  94. static void amiga_updatewindowparameters(struct window_amiga *win);
  95. static void amiga_deletewindow(struct window_amiga *win);
  96. static struct window_amiga *amiga_createwindow(struct screen_amiga *scr, int width, int height, int x, int y, BOOL borderless, BOOL sizable);
  97.  
  98.  
  99.  
  100.  
  101. /* 
  102. **    screen_amiga = amiga_createscreen(scrtitle)
  103. */
  104.  
  105. static struct screen_amiga *amiga_createscreen(char *title)
  106. {
  107.     struct screen_amiga *scr = kn_alloc0(sizeof(struct screen_amiga));
  108.     if (scr)
  109.     {    
  110.         scr->title = TStrDup(TNULL, title ? title : "TEKlib visual");
  111.         if (scr->title)
  112.         {
  113.             #define GfxBase            scr->gfxbase
  114.             #define IntuitionBase    scr->intuitionbase
  115.             #define GadToolsBase    scr->gadtoolsbase
  116.             #define GuiGFXBase        scr->guigfxbase
  117.     
  118.             /* 
  119.             **    required libraries
  120.             */
  121.     
  122.             GfxBase = OpenLibrary("graphics.library", 0);
  123.             IntuitionBase = OpenLibrary("intuition.library", 0);
  124.             GadToolsBase = OpenLibrary("gadtools.library", 0);
  125.             GuiGFXBase = OpenLibrary("guigfx.library", 16);
  126.         
  127.             if (GfxBase && IntuitionBase && GadToolsBase && GuiGFXBase)
  128.             {
  129.                 scr->screen = LockPubScreen(NULL);
  130.                 if (scr->screen)
  131.                 {
  132.                     ScreenToFront(scr->screen);
  133.                     return scr;
  134.                 }
  135.             }
  136.  
  137.             CloseLibrary(GuiGFXBase);
  138.             CloseLibrary(GadToolsBase);
  139.             CloseLibrary(IntuitionBase);
  140.             CloseLibrary(GfxBase);
  141.     
  142.             #undef GfxBase
  143.             #undef IntuitionBase
  144.             #undef GadToolsBase
  145.             #undef GuiGFXBase
  146.             
  147.             TMMUFree(TNULL, scr->title);
  148.         }
  149.         
  150.         kn_free(scr);
  151.     }
  152.     
  153.     return NULL;
  154. }
  155.  
  156.  
  157. /*
  158. **
  159. **    amiga_deletescreen(scr)
  160. **    
  161. **    delete amiga screen
  162. **
  163. */
  164.  
  165. static void amiga_deletescreen(struct screen_amiga *scr)
  166. {
  167.     if (scr)
  168.     {
  169.         #define GfxBase            scr->gfxbase
  170.         #define IntuitionBase    scr->intuitionbase
  171.         #define GadToolsBase    scr->gadtoolsbase
  172.         #define GuiGFXBase        scr->guigfxbase
  173.  
  174.         if (scr->screen)
  175.         {
  176.             UnlockPubScreen(NULL, scr->screen);
  177.         }
  178.  
  179.         CloseLibrary(GuiGFXBase);
  180.         CloseLibrary(GadToolsBase);
  181.         CloseLibrary(IntuitionBase);
  182.         CloseLibrary(GfxBase);
  183.  
  184.         #undef GfxBase
  185.         #undef IntuitionBase
  186.         #undef GadToolsBase
  187.         #undef GuiGFXBase
  188.  
  189.         TMMUFree(TNULL, scr->title);
  190.         kn_free(scr);
  191.     }
  192. }
  193.  
  194.  
  195.  
  196. /*
  197. **    window_amiga = amiga_createwindow(scr, int w, int h, int x, int y, borderless, sizable)
  198. **
  199. **    open an amiga window.
  200. **
  201. */
  202.  
  203. static struct window_amiga *amiga_createwindow(struct screen_amiga *scr, int width, int height, int x, int y, BOOL borderless, BOOL sizable)
  204. {
  205.     #define IntuitionBase scr->intuitionbase
  206.     #define GfxBase scr->gfxbase
  207.     #define GuiGFXBase scr->guigfxbase
  208.     #define GadToolsBase scr->gadtoolsbase
  209.  
  210.     if (scr)
  211.     {
  212.         struct window_amiga *win = kn_alloc(sizeof(struct window_amiga));
  213.         if (win)
  214.         {
  215.             WORD viswidth, visheight, visleft, vistop, vismidx, vismidy;
  216.             WORD borderwidth = 0, borderheight = 0;
  217.             ULONG modeID, flags;
  218.         
  219.             struct TagItem taglist[20], *tp;
  220.             tp = taglist;
  221.  
  222.  
  223.             /* 
  224.             **    determine the screen's visible area.
  225.             */
  226.  
  227.             viswidth = scr->screen->Width;
  228.             visheight = scr->screen->Height;
  229.  
  230.             modeID = GetVPModeID(&scr->screen->ViewPort);
  231.             if (modeID)
  232.             {
  233.                 DisplayInfoHandle dih = FindDisplayInfo(modeID);
  234.                 if (dih)
  235.                 {
  236.                     struct DimensionInfo di;
  237.                     if (GetDisplayInfoData(dih, (UBYTE *) &di, sizeof(di), DTAG_DIMS, modeID))
  238.                     {
  239.                         viswidth = di.TxtOScan.MaxX - di.TxtOScan.MinX + 1;
  240.                         visheight = di.TxtOScan.MaxY - di.TxtOScan.MinY + 1;
  241.                     }
  242.                 }
  243.             }
  244.             
  245.             visleft = -scr->screen->ViewPort.DxOffset;
  246.             vistop = -scr->screen->ViewPort.DyOffset;
  247.             
  248.             vismidx = (viswidth >> 1) - scr->screen->ViewPort.DxOffset;
  249.             vismidy = (visheight >> 1) - scr->screen->ViewPort.DyOffset;
  250.  
  251.  
  252.             /* 
  253.             **    by default, don't let our window obscure the screen's title bar.
  254.             */
  255.             
  256.             if (vistop < scr->screen->BarHeight + 1)
  257.             {
  258.                 vistop += scr->screen->BarHeight + 1;
  259.                 visheight -= scr->screen->BarHeight + 1;
  260.                 vismidy += (scr->screen->BarHeight + 1) >> 1;
  261.             }
  262.  
  263.  
  264.  
  265.             /* 
  266.             **    determine window size
  267.             */
  268.             
  269.             if (width > 0 || height > 0)
  270.             {
  271.                 /*
  272.                 **    use preferred size
  273.                 */
  274.  
  275.                 if (!borderless)
  276.                 {
  277.                     borderwidth = scr->screen->WBorLeft + scr->screen->WBorRight;
  278.                     borderheight = scr->screen->WBorTop + scr->screen->Font->ta_YSize + 1 + scr->screen->WBorBottom;
  279.                 
  280.                     if (sizable)
  281.                     {
  282.                         borderheight += 8;        
  283.  
  284.                         /* WFLG_SIZEBBOTTOM default. that does not cover hacks like sysihack or visualprefs.
  285.                         ** i don't know a legal way to determine the patched value. */
  286.                     }
  287.                 }
  288.  
  289.  
  290.                 tp->ti_Tag = WA_InnerWidth; tp->ti_Data = width; tp++;
  291.                 tp->ti_Tag = WA_InnerHeight; tp->ti_Data = height; tp++;
  292.             }
  293.             else
  294.             {
  295.                 /* 
  296.                 **    by default, let the window be 2/3 the size of the screen's visible area
  297.                 */
  298.  
  299.                 width = (viswidth << 1) / 3;
  300.                 height = (visheight << 1) / 3;
  301.                 
  302.                 tp->ti_Tag = WA_InnerWidth; tp->ti_Data = width; tp++;
  303.                 tp->ti_Tag = WA_InnerHeight; tp->ti_Data = height; tp++;
  304.             }
  305.  
  306.  
  307.             /* 
  308.             **    determine window position
  309.             */
  310.     
  311.             if (x < 0 && y < 0)
  312.             {
  313.                 /* 
  314.                 **    by default, open centered
  315.                 */
  316.                 
  317.                 x = vismidx - ((width + borderwidth) >> 1);
  318.                 y = vismidy - ((height + borderheight) >> 1);
  319.             }
  320.     
  321.             tp->ti_Tag = WA_Left; tp->ti_Data = x; tp++;
  322.             tp->ti_Tag = WA_Top; tp->ti_Data = y; tp++;
  323.  
  324.  
  325.             /* 
  326.             **    misc initializations.
  327.             */
  328.             
  329.             tp->ti_Tag = WA_PubScreen; tp->ti_Data = (ULONG) scr->screen; tp++;
  330.             tp->ti_Tag = WA_NewLookMenus; tp->ti_Data = TRUE; tp++;
  331.             tp->ti_Tag = WA_RMBTrap; tp->ti_Data = TRUE; tp++;
  332.  
  333.             flags = WFLG_SMART_REFRESH | WFLG_REPORTMOUSE;
  334.  
  335.             if (!borderless)
  336.             {
  337.                 tp->ti_Tag = WA_Title; tp->ti_Data = (ULONG) scr->title; tp++;
  338.                 
  339.                 flags |= WFLG_DRAGBAR | WFLG_GIMMEZEROZERO | WFLG_DEPTHGADGET | WFLG_ACTIVATE | WFLG_CLOSEGADGET;
  340.                             
  341.                 if (sizable)
  342.                 {
  343.                     flags |= WFLG_SIZEBBOTTOM | WFLG_SIZEGADGET;
  344.  
  345.                     tp->ti_Tag = WA_MinWidth; tp->ti_Data = borderwidth + 1; tp++;
  346.                     tp->ti_Tag = WA_MinHeight; tp->ti_Data = borderheight + 1; tp++;
  347.                     tp->ti_Tag = WA_MaxWidth; tp->ti_Data = viswidth; tp++;
  348.                     tp->ti_Tag = WA_MaxHeight; tp->ti_Data = visheight; tp++;
  349.  
  350.                     /* 
  351.                     **    alternate window position.
  352.                     */
  353.         
  354.                     win->otherwinpos[0] = visleft;
  355.                     win->otherwinpos[1] = vistop;
  356.                     win->otherwinpos[2] = viswidth;
  357.                     win->otherwinpos[3] = visheight;
  358.                     tp->ti_Tag = WA_Zoom; tp->ti_Data = (ULONG) win->otherwinpos; tp++;
  359.                 }
  360.             }
  361.             else
  362.             {
  363.                 flags |= WFLG_BORDERLESS | WFLG_BACKDROP;
  364.             }
  365.  
  366.             tp->ti_Tag = WA_Flags; tp->ti_Data = flags; tp++;
  367.  
  368.             win->idcmpmask = 0;
  369.             tp->ti_Tag = WA_IDCMP; tp->ti_Data = win->idcmpmask; tp++;
  370.  
  371.             tp->ti_Tag = TAG_DONE;
  372.             
  373.             if ((win->window = OpenWindowTagList(NULL, taglist)))
  374.             {
  375.                 win->scr = scr;
  376.                 win->sizable = sizable;
  377.  
  378.                 amiga_updatewindowparameters(win);
  379.  
  380.                 SetABPenDrMd(win->window->RPort, 1, 0, JAM2);
  381.  
  382.             #if 0                
  383.                 if (scr->screenfont)
  384.                 {
  385.                     SetFont(win->window->RPort, scr->screenfont);
  386.                 }
  387.             #endif
  388.                 
  389.                 ActivateWindow(win->window);
  390.         
  391.                 return win;
  392.             }
  393.             
  394.             kn_free(win);
  395.         }
  396.     }        
  397.  
  398.     #undef GadToolsBase
  399.     #undef IntuitionBase
  400.     #undef GfxBase
  401.     #undef GuiGFXBase
  402.     
  403.     return NULL;
  404. }
  405.  
  406.  
  407. /*
  408. **
  409. **    amiga_deletewindow(window)
  410. **
  411. **    delete an amiga window
  412. **
  413. */
  414.  
  415. static void amiga_deletewindow(struct window_amiga *win)
  416. {
  417.     if (win)
  418.     {
  419.         #define IntuitionBase win->scr->intuitionbase
  420.         CloseWindow(win->window);
  421.         #undef IntuitionBase
  422.         kn_free(win);
  423.     }
  424. }
  425.  
  426.  
  427.  
  428.  
  429.  
  430. /*
  431. **    amiga_updatewindowparameters(win)
  432. **
  433. **    get current window dimensions
  434. **
  435. */
  436.  
  437. static void amiga_updatewindowparameters(struct window_amiga *win)
  438. {
  439.     if (win)
  440.     {
  441.         win->winwidth = win->window->Width;
  442.         win->winheight = win->window->Height;
  443.         win->innerwidth = win->winwidth - win->window->BorderLeft - win->window->BorderRight;
  444.         win->innerheight = win->winheight - win->window->BorderTop - win->window->BorderBottom;
  445.     }
  446. }
  447.  
  448.  
  449.  
  450.  
  451.  
  452. /* 
  453. **    kn_createvisual
  454. **
  455. */
  456.  
  457. TAPTR kn_createvisual(TAPTR mmu, TSTRPTR preftitle, TINT prefw, TINT prefh)
  458. {
  459.     struct visual_amiga *visual;
  460.     BOOL success = FALSE;
  461.  
  462.     visual = kn_alloc0(sizeof(struct visual_amiga));
  463.     if (visual)
  464.     {
  465.         visual->screen = amiga_createscreen(preftitle);
  466.         if (visual->screen)
  467.         {
  468.             BOOL borderless = FALSE;
  469.             BOOL sizable = TRUE;    
  470.  
  471.             int winleft, wintop;
  472.             
  473.             winleft = -1;
  474.             wintop = -1;
  475.         
  476.             visual->window = amiga_createwindow(visual->screen, prefw, prefh, winleft, wintop, borderless, sizable);
  477.             if (visual->window)
  478.             {
  479.                 success = TRUE;
  480.             }
  481.         }    
  482.     }
  483.  
  484.     if (!success)
  485.     {
  486.         kn_destroyvisual(visual);
  487.         visual = NULL;
  488.     }
  489.  
  490.     return visual;
  491. }
  492.  
  493.  
  494.  
  495. /* 
  496. **    kn_destroyvisual
  497. **
  498. */
  499.  
  500. TVOID kn_destroyvisual(TAPTR v)
  501. {
  502.     struct visual_amiga *visual = (struct visual_amiga *) v;
  503.  
  504.     #define GfxBase visual->screen->gfxbase
  505.     #define GuiGFXBase visual->screen->guigfxbase
  506.  
  507.     if (visual)
  508.     {
  509.         int i;
  510.         
  511.         DeleteDirectDrawHandle(visual->ddh);
  512.         ReleaseDrawHandle(visual->drawhandle);
  513.         
  514.         for (i = 0; i < 256; ++i)
  515.         {
  516.             while (visual->amigapentab[i]--)
  517.             {
  518.                 ReleasePen(visual->screen->screen->ViewPort.ColorMap, (ULONG) i);
  519.             }
  520.         }
  521.     
  522.         amiga_deletewindow(visual->window);
  523.         amiga_deletescreen(visual->screen);
  524.         kn_free(visual);
  525.     }
  526.     
  527.     #undef GuiGFXBase
  528.     #undef GfxBase
  529. }
  530.  
  531.  
  532.  
  533. /*
  534. **
  535. **    newinput = kn_getnextinput(visual, newimsg, eventmask)
  536. **
  537. **    get next input event from visual object
  538. **    and fill it into the supplied TIMSG structure.
  539. **
  540. **    returns TTRUE, when there was a new message filled into the
  541. **    newimsg structure, otherwise TFALSE
  542. **
  543. */
  544.  
  545. TBOOL kn_getnextinput(TAPTR v, TIMSG *newimsg, TUINT eventmask)
  546. {    
  547.     struct visual_amiga *visual = (struct visual_amiga *) v;
  548.     struct IntuiMessage *amiga_imsg;
  549.  
  550.     if (!visual->window->window->UserPort)
  551.     {
  552.         return TFALSE;
  553.     }
  554.  
  555.     #define GadToolsBase visual->screen->gadtoolsbase
  556.  
  557.     newimsg->type = TITYPE_NONE;
  558.     amiga_imsg = GT_GetIMsg(visual->window->window->UserPort);
  559.     if (amiga_imsg)
  560.     {
  561.         switch (amiga_imsg->Class)
  562.         {
  563.             case ACTIVEWINDOW:
  564.                 newimsg->type = TITYPE_VISUAL_FOCUS;
  565.                 break;
  566.  
  567.             case INACTIVEWINDOW:
  568.                 newimsg->type = TITYPE_VISUAL_UNFOCUS;
  569.                 break;
  570.  
  571.             case MOUSEMOVE:
  572.                 newimsg->type = TITYPE_MOUSEMOVE;
  573.                 break;
  574.                 
  575.             case MOUSEBUTTONS:
  576.                 switch (amiga_imsg->Code)
  577.                 {
  578.                     case SELECTUP:
  579.                         newimsg->type = TITYPE_MOUSEBUTTON;
  580.                         newimsg->code = TMBCODE_LEFTUP;
  581.                         break;                
  582.     
  583.                     case SELECTDOWN:
  584.                         newimsg->type = TITYPE_MOUSEBUTTON;
  585.                         newimsg->code = TMBCODE_LEFTDOWN;
  586.                         break;                
  587.  
  588.                     case MENUUP:
  589.                         newimsg->type = TITYPE_MOUSEBUTTON;
  590.                         newimsg->code = TMBCODE_RIGHTUP;
  591.                         break;                
  592.     
  593.                     case MENUDOWN:
  594.                         newimsg->type = TITYPE_MOUSEBUTTON;
  595.                         newimsg->code = TMBCODE_RIGHTDOWN;
  596.                         break;                
  597.                 }
  598.                 break;
  599.             
  600.             case CLOSEWINDOW:
  601.                 newimsg->type = TITYPE_VISUAL_CLOSE;
  602.                 break;
  603.             
  604.             case NEWSIZE:
  605.                 amiga_updatewindowparameters(visual->window);
  606.                 newimsg->type = TITYPE_VISUAL_NEWSIZE;
  607.                 newimsg->width = visual->window->innerwidth;
  608.                 newimsg->height = visual->window->innerheight;
  609.                 break;
  610.             
  611.             case REFRESHWINDOW:
  612.                 break;
  613.  
  614.             case RAWKEY:
  615.                 if (amiga_imsg->Code >= 80 && amiga_imsg->Code <= 89)
  616.                 {
  617.                     newimsg->type = TITYPE_KEY;
  618.                     newimsg->code = TKEYCODE_F1 + amiga_imsg->Code - 80;
  619.                 }
  620.                 else
  621.                 {
  622.                     switch (amiga_imsg->Code)
  623.                     {
  624.                         case 95:
  625.                             newimsg->type = TITYPE_KEY;
  626.                             newimsg->code = TKEYCODE_HELP;
  627.                             break;
  628.                         case 76:
  629.                             newimsg->type = TITYPE_KEY;
  630.                             newimsg->code = TKEYCODE_CRSRUP;
  631.                             break;
  632.                         case 77:
  633.                             newimsg->type = TITYPE_KEY;
  634.                             newimsg->code = TKEYCODE_CRSRDOWN;
  635.                             break;
  636.                         case 78:
  637.                             newimsg->type = TITYPE_KEY;
  638.                             newimsg->code = TKEYCODE_CRSRRIGHT;
  639.                             break;
  640.                         case 79:
  641.                             newimsg->type = TITYPE_KEY;
  642.                             newimsg->code = TKEYCODE_CRSRLEFT;
  643.                             break;
  644.                     }
  645.                 }
  646.                 break;
  647.  
  648.             case VANILLAKEY:
  649.                 switch (amiga_imsg->Code)
  650.                 {
  651.                     case 27:
  652.                         newimsg->type = TITYPE_KEY;
  653.                         newimsg->code = TKEYCODE_ESC;
  654.                         break;
  655.  
  656.                     case 8:
  657.                         newimsg->type = TITYPE_KEY;
  658.                         newimsg->code = TKEYCODE_BCKSPC;
  659.                         break;
  660.  
  661.                     case 9:
  662.                         newimsg->type = TITYPE_KEY;
  663.                         newimsg->code = TKEYCODE_TAB;
  664.                         break;
  665.  
  666.                     case 13:
  667.                         newimsg->type = TITYPE_KEY;
  668.                         newimsg->code = TKEYCODE_ENTER;
  669.                         break;
  670.  
  671.                     case 127:
  672.                         newimsg->type = TITYPE_KEY;
  673.                         newimsg->code = TKEYCODE_DEL;
  674.                         break;
  675.  
  676.                     default:
  677.                         newimsg->type = TITYPE_KEY;
  678.                         newimsg->code = (TUINT) amiga_imsg->Code;
  679.                 }
  680.                 break;        
  681.         }
  682.  
  683.         if (newimsg->type & eventmask)
  684.         {
  685.             newimsg->mousex = amiga_imsg->MouseX - visual->window->window->BorderLeft;
  686.             newimsg->mousey = amiga_imsg->MouseY - visual->window->window->BorderTop;
  687.             newimsg->qualifier = 0;
  688.         
  689.             if (amiga_imsg->Qualifier & IEQUALIFIER_LSHIFT)
  690.             {
  691.                 newimsg->qualifier |= TKEYQUAL_LEFT_SHIFT;        
  692.             }
  693.             if (amiga_imsg->Qualifier & IEQUALIFIER_RSHIFT)
  694.             {
  695.                 newimsg->qualifier |= TKEYQUAL_RIGHT_SHIFT;        
  696.             }
  697.             if (amiga_imsg->Qualifier & IEQUALIFIER_CONTROL)
  698.             {
  699.                 newimsg->qualifier |= TKEYQUAL_LEFT_CONTROL;
  700.             }
  701.             if (amiga_imsg->Qualifier & IEQUALIFIER_LALT)
  702.             {
  703.                 newimsg->qualifier |= TKEYQUAL_LEFT_ALT;
  704.             }
  705.             if (amiga_imsg->Qualifier & IEQUALIFIER_RALT)
  706.             {
  707.                 newimsg->qualifier |= TKEYQUAL_RIGHT_ALT;
  708.             }
  709.             if (amiga_imsg->Qualifier & IEQUALIFIER_LCOMMAND)
  710.             {
  711.                 newimsg->qualifier |= TKEYQUAL_LEFT_PROPRIETARY;
  712.             }
  713.             if (amiga_imsg->Qualifier & IEQUALIFIER_RCOMMAND)
  714.             {
  715.                 newimsg->qualifier |= TKEYQUAL_RIGHT_PROPRIETARY;
  716.             }
  717.             if (amiga_imsg->Qualifier & IEQUALIFIER_NUMERICPAD)
  718.             {
  719.                 newimsg->qualifier |= TKEYQUAL_NUMBLOCK;
  720.             }
  721.         }
  722.         
  723.         GT_ReplyIMsg(amiga_imsg);
  724.     }
  725.  
  726.     #undef GadToolsBase
  727.  
  728.     return (newimsg->type & eventmask);
  729. }
  730.  
  731.  
  732.  
  733. /*
  734. **    kn_setinputmask(visual, inputmask)
  735. **
  736. **    set a new mask of input events to be reported
  737. **    
  738. */
  739.  
  740. TVOID kn_setinputmask(TAPTR v, TUINT eventmask)
  741. {
  742.     struct visual_amiga *visual = (struct visual_amiga *) v;
  743.     ULONG idcmp = 0;
  744.  
  745.     #define IntuitionBase visual->screen->intuitionbase
  746.  
  747.     if (eventmask & TITYPE_VISUAL_CLOSE) idcmp |= IDCMP_CLOSEWINDOW;
  748.     if (eventmask & TITYPE_VISUAL_FOCUS) idcmp |= IDCMP_ACTIVEWINDOW;
  749.     if (eventmask & TITYPE_VISUAL_UNFOCUS) idcmp |= IDCMP_INACTIVEWINDOW;
  750.     if ((eventmask & TITYPE_VISUAL_NEWSIZE) && visual->window->sizable) idcmp |= IDCMP_NEWSIZE;
  751.     if (eventmask & TITYPE_KEY) idcmp |= IDCMP_VANILLAKEY | IDCMP_RAWKEY;
  752.     if (eventmask & TITYPE_MOUSEMOVE) idcmp |= IDCMP_MOUSEMOVE;
  753.     if (eventmask & TITYPE_MOUSEBUTTON) idcmp |= IDCMP_MOUSEBUTTONS;
  754.     
  755.     if (idcmp != visual->window->idcmpmask)
  756.     {
  757.         ModifyIDCMP(visual->window->window, idcmp);
  758.         visual->window->idcmpmask = idcmp;
  759.     }
  760.     
  761.     #undef IntuitionBase
  762. }
  763.  
  764.  
  765.  
  766.  
  767.  
  768. /*
  769. **    pen = kn_allocpen(visual, rgb)
  770. **
  771. **    allocate a coloured pen (rgbcolor format: 0x00rrggbb).
  772. **    0xffffffff if out of pens.
  773. */
  774.  
  775. TAPTR kn_allocpen(TAPTR v, TUINT rgb)
  776. {
  777.     struct visual_amiga *visual = (struct visual_amiga *) v;
  778.  
  779.     #define GfxBase visual->screen->gfxbase
  780.  
  781.     ULONG r, g, b;
  782.     LONG amigapen;
  783.  
  784.     r = (rgb & 0xff0000); r = r | (r << 8); r = r | (r >> 16);
  785.     g = (rgb & 0x00ff00); g = g | (g >> 8); g = g | (g << 16);
  786.     b = (rgb & 0x0000ff); b = b | (b << 8); b = b | (b << 16);
  787.  
  788.     amigapen = ObtainBestPen(visual->screen->screen->ViewPort.ColorMap, r,g,b, TAG_DONE);
  789.  
  790.     visual->amigapentab[amigapen]++;
  791.  
  792.     #undef GfxBase
  793.     
  794.     return (TAPTR) amigapen;
  795. }
  796.  
  797.  
  798.  
  799. /*
  800. **    kn_freepen(visual, pen-nr)
  801. **
  802. **    free a coloured pen
  803. */
  804.  
  805. TVOID kn_freepen(TAPTR v, TAPTR pen)
  806. {
  807.     struct visual_amiga *visual = (struct visual_amiga *) v;
  808.  
  809.     #define GfxBase visual->screen->gfxbase
  810.  
  811.     if ((ULONG) pen > 0)
  812.     {
  813.         ReleasePen(visual->screen->screen->ViewPort.ColorMap, (ULONG) pen);
  814.         visual->amigapentab[(ULONG) pen]--;    
  815.     }
  816.  
  817.     #undef GfxBase
  818. }
  819.  
  820.  
  821. /*
  822. **    kn_setbgpen(visual, pen)
  823. **
  824. **    set background pen
  825. */
  826.  
  827. TVOID kn_setbgpen(TAPTR v, TAPTR pen)
  828. {
  829.     struct visual_amiga *visual = (struct visual_amiga *) v;
  830.  
  831.     #define GfxBase visual->screen->gfxbase
  832.  
  833.     SetBPen(visual->window->window->RPort, (ULONG) pen);
  834.     visual->bgpen = (ULONG) pen;
  835.  
  836.     #undef GfxBase
  837. }
  838.  
  839.  
  840. /*
  841. **    kn_setfgpen(visual, pen)
  842. **
  843. **    set foreground pen
  844. */
  845.  
  846. TVOID kn_setfgpen(TAPTR v, TAPTR pen)
  847. {
  848.     struct visual_amiga *visual = (struct visual_amiga *) v;
  849.  
  850.     #define GfxBase visual->screen->gfxbase
  851.  
  852.     SetAPen(visual->window->window->RPort, (ULONG) pen);
  853.     visual->fgpen = (ULONG) pen;
  854.  
  855.     #undef GfxBase
  856. }
  857.  
  858.  
  859. /*
  860. **    kn_line(visual, x,y,x2,y2)
  861. **
  862. **    line
  863. */
  864.  
  865. TVOID kn_line(TAPTR v, TINT x1, TINT y1, TINT x2, TINT y2)
  866. {
  867.     struct visual_amiga *visual = (struct visual_amiga *) v;
  868.  
  869.     #define GfxBase visual->screen->gfxbase
  870.  
  871.     Move(visual->window->window->RPort, (LONG) x1, (LONG) y1);
  872.     Draw(visual->window->window->RPort, (LONG) x2, (LONG) y2);
  873.     
  874.     #undef GfxBase
  875. }
  876.  
  877.  
  878.  
  879. /*
  880. **    kn_frect(visual, x, y, w, h)
  881. **
  882. **    filled rectangle
  883. */
  884.  
  885. TVOID kn_frect(TAPTR v, TINT x, TINT y, TINT w, TINT h)
  886. {
  887.     struct visual_amiga *visual = (struct visual_amiga *) v;
  888.  
  889.     #define GfxBase visual->screen->gfxbase
  890.  
  891.     RectFill(visual->window->window->RPort, (LONG) x, (LONG) y, (LONG) x + w - 1, (LONG) y + h - 1);
  892.  
  893.     #undef GfxBase
  894. }
  895.  
  896.  
  897.  
  898. /*
  899. **    kn_rect(visual, x, y, w, h)
  900. **
  901. **    outline rectangle
  902. */
  903.  
  904. TVOID kn_rect(TAPTR v, TINT x, TINT y, TINT w, TINT h)
  905. {
  906.     struct visual_amiga *visual = (struct visual_amiga *) v;
  907.  
  908.     #define GfxBase visual->screen->gfxbase
  909.  
  910.     Move(visual->window->window->RPort, (LONG) x, (LONG) y);
  911.     Draw(visual->window->window->RPort, (LONG) x+w-1, (LONG) y);
  912.     Draw(visual->window->window->RPort, (LONG) x+w-1, (LONG) y+h-1);
  913.     Draw(visual->window->window->RPort, (LONG) x, (LONG) y+h-1);
  914.     Draw(visual->window->window->RPort, (LONG) x, (LONG) y);
  915.     
  916.     #undef GfxBase
  917. }
  918.  
  919.  
  920. /*
  921. **    kn_plot(visual, x, y)
  922. **
  923. **    plot
  924. */
  925.  
  926. TVOID kn_plot(TAPTR v, TINT x, TINT y)
  927. {
  928.     struct visual_amiga *visual = (struct visual_amiga *) v;
  929.  
  930.     #define GfxBase visual->screen->gfxbase
  931.  
  932.     Move(visual->window->window->RPort, (LONG) x, (LONG) y);
  933.     Draw(visual->window->window->RPort, (LONG) x, (LONG) y);
  934.     
  935.     #undef GfxBase
  936. }
  937.  
  938.  
  939.  
  940. /*
  941. **    kn_getparameters(visual, visualparameters)
  942. **
  943. **    fill a visual parameters structure
  944. */
  945.  
  946. TVOID kn_getparameters(TAPTR v, struct knvisual_parameters *p)
  947. {
  948.     struct visual_amiga *visual = (struct visual_amiga *) v;
  949.  
  950.     amiga_updatewindowparameters(visual->window);    
  951.     p->fontwidth = visual->window->window->RPort->TxWidth;
  952.     p->fontheight = visual->window->window->RPort->TxHeight;
  953.     p->pixelwidth = visual->window->innerwidth;
  954.     p->pixelheight = visual->window->innerheight;
  955.     p->textwidth = visual->window->innerwidth / p->fontwidth;
  956.     p->textheight = visual->window->innerheight / p->fontheight;
  957. }
  958.  
  959.  
  960.  
  961. /*
  962. **    kn_scroll(visual, x, y, w, h, dx, dy)
  963. **
  964. **    scroll rectangle
  965. **    
  966. */
  967.  
  968. TVOID kn_scroll(TAPTR v, TINT x, TINT y, TINT w, TINT h, TINT dx, TINT dy)
  969. {
  970.     struct visual_amiga *visual = (struct visual_amiga *) v;
  971.  
  972.     #define GfxBase visual->screen->gfxbase
  973.  
  974.     ScrollRaster(visual->window->window->RPort, (LONG) dx, (LONG) dy, (LONG) x, (LONG) y, (LONG) x + w - 1, (LONG) y + h - 1);
  975.  
  976.     #undef GfxBase
  977. }
  978.  
  979.  
  980.  
  981. /*
  982. **    kn_drawtext(visual, x, y, text, len)
  983. **
  984. **    write text to text cursor position
  985. **    
  986. */
  987.  
  988. TVOID kn_drawtext(TAPTR v, TINT x, TINT y, TSTRPTR text, TUINT len)
  989. {
  990.     struct visual_amiga *visual = (struct visual_amiga *) v;
  991.  
  992.     #define GfxBase visual->screen->gfxbase
  993.  
  994.     if (text && len > 0)
  995.     {
  996.         Move(visual->window->window->RPort, 
  997.             (LONG) x * visual->window->window->RPort->TxWidth, 
  998.             (LONG) y * visual->window->window->RPort->TxHeight +
  999.             visual->window->window->RPort->TxBaseline);
  1000.             
  1001.         Text(visual->window->window->RPort, text, (ULONG) len);
  1002.     }
  1003.  
  1004.     #undef GfxBase
  1005. }
  1006.  
  1007.  
  1008.  
  1009. /*
  1010. **    kn_waitvisual(visual, timer, knevent)
  1011. **
  1012. **    wait for visual or supplied event, or optionally for a timer
  1013. **    
  1014. */
  1015.  
  1016. TBOOL kn_waitvisual(TAPTR v, TKNOB *timer, TKNOB *evt)
  1017. {
  1018.     struct visual_amiga *visual = (struct visual_amiga *) v;
  1019.     ULONG visualsig = (1L << visual->window->window->UserPort->mp_SigBit);
  1020.  
  1021.     return (Wait(visualsig | (1L << ((struct amievent *) evt)->signal)) & visualsig);
  1022. }
  1023.  
  1024.  
  1025.  
  1026. /* 
  1027. **    kn_sync    
  1028. **
  1029. */
  1030.  
  1031. TVOID kn_flush(TAPTR v, TINT x, TINT y, TINT w, TINT h)
  1032. {
  1033. }
  1034.  
  1035.  
  1036.  
  1037. /*
  1038. **    kn_drawrgb(visual, buf, x,y,w,h,totwidth)
  1039. **
  1040. **    draw RGB buffer
  1041. **    
  1042. */
  1043.  
  1044. TVOID kn_drawrgb(TAPTR v, TUINT *buf, TINT x, TINT y, TINT w, TINT h, TINT totwidth)
  1045. {
  1046.     struct visual_amiga *visual = (struct visual_amiga *) v;
  1047.  
  1048.     #define GuiGFXBase visual->screen->guigfxbase
  1049.     
  1050.     if (GuiGFXBase)
  1051.     {
  1052.         if (!visual->drawhandle)
  1053.         {
  1054.             visual->drawhandle = ObtainDrawHandleA(NULL, visual->window->window->RPort,
  1055.                 visual->screen->screen->ViewPort.ColorMap, TNULL);
  1056.         }
  1057.         
  1058.         if (visual->drawhandle)
  1059.         {
  1060.             if (visual->ddh)
  1061.             {
  1062.                 if (w != visual->ddhw || h != visual->ddhh)
  1063.                 {
  1064.                     DeleteDirectDrawHandle(visual->ddh);
  1065.                     visual->ddh = TNULL;
  1066.                 }
  1067.             }
  1068.         
  1069.             if (!visual->ddh)
  1070.             {
  1071.                 visual->ddh = CreateDirectDrawHandleA(visual->drawhandle, w, h, w, h, TNULL);
  1072.                 visual->ddhw = w;
  1073.                 visual->ddhh = h;
  1074.             }
  1075.             
  1076.             if (visual->ddh)
  1077.             {
  1078.                 DirectDrawTrueColor(visual->ddh, (ULONG *) buf, x, y, 
  1079.                     GGFX_SourceWidth, totwidth, TAG_DONE);
  1080.             }
  1081.         }
  1082.     }
  1083.     
  1084.     #undef GuiGFXBase
  1085. }
  1086.  
  1087.  
  1088. #undef SysBase
  1089.